#include "CRoP_AMM.h"

CRoP_AMM::CRoP_AMM(int argc, char **argv) {
	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &p);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	printf("# of processes %d", p);
}

void CRoP_AMM::parse_file(const char * filename) {

//    Broadcast each B.row/A.col pair
}

int CRoP_AMM::val(int x, INT_INT_MAP &h) {
	if (h.find(x) != h.end()) {
		srand(x);
		(h)[x] = int(rand() * p);
	}
	return h[x];
}

void CRoP_AMM::do_product(ENTRY_VEC col, ENTRY_VEC row, int count[]) {
	ENTRY_VEC::iterator it = row.begin();
	for (; it != row.end(); it++) {
		int a_idx = (p + rank - (*it).hash) % p;
		ENTRY_VEC::iterator begin = col.begin() + count[a_idx];
		ENTRY_VEC::iterator end = col.begin() + count[a_idx + 1];
		for (begin; begin != end; begin++) {
			// Add to spacesaving
			// Do multiply *it.val x (*begin).val;
		}
	}
}

void CRoP_AMM::crop(FLOAT_VEC col, FLOAT_VEC row) {
	ENTRY_VEC h1val, h2val;
	FLOAT_VEC::iterator it = col.begin();
	INT_VEC count = INT_VEC(p);
	int counts[p + 1];
	fill(counts, counts + p + 1, 0);

	//todo::change to iterator
	for (int i = 0; i < col.size(); i++) {
		float w = col[i];
		if (w == 0)
			continue;
		int hash1 = val(i, h1);
		count.at(hash1)++;counts
		[hash1 + 1]++;
		h1val.push_back(Entry(hash1, i, w));
	}

	for (int i = 0; i < row.size(); i++) {
		float w = row[i];
		if (row[i] == 0)
			continue;
		h2val.push_back(Entry(val(i, h2), i, w));
	}

	sort(h1val.begin(), h1val.end(), compare);

	for (int i = 1; i < p + 1; i++) {
		counts[i] = counts[i - 1] + counts[i];
	}

	do_product(h1val, h2val, counts);
}

int main(int argc, char **argv) {
	CRoP_AMM crop = CRoP_AMM(argc, argv);

//	cout << "Starting CRoP" << endl;
//    int rank, size;
//	MPI_Init (&argc, &argv);
//	MPI_Comm_rank (MPI_COMM_WORLD, &rank);
//	MPI_Comm_size (MPI_COMM_WORLD, &size);
//	printf( "Hello world from process %d of %d\n", rank, size );
//	MPI_Finalize();
	MPI_Finalize();
	return 1;
}
